package cn.qy.kotlin.base

import java.io.File

/**
 * List 与 Set, Map
 */
val patronList = listOf("AAA", "BBB", "CCC")

fun main() {
    println(patronList)
    println(patronList[0])
    println(patronList.first())
    println(patronList.random())
    println(patronList.last())

    val fifthPatron = patronList.getOrNull(4) ?: "Unknown Patron"
    println(fifthPatron)

    val orElse = patronList.getOrElse(5) { 12345 }
    println(orElse)

    // 检查列表内容
    println(patronList.contains("BBB"))
    println(patronList.contains("DDD"))
    println(patronList.containsAll(setOf("AAA", "DDD")))

    val toMutableList = patronList.toMutableList()
    toMutableList.remove("BBB")
    toMutableList.add("Alex")
    println(toMutableList)

    // 使用赋值操作符修改列表内容
    toMutableList[1] = "XXX".also { println(toMutableList) }
    println(toMutableList)

    // 能修改可变列表的函数有个统一的名字：mutator 函数。
    toMutableList += "baba"
    println(toMutableList)

    // 遍历方式一
    for (patron in patronList) {
        println("Good evening, $patron")
    }
    // 遍历方式二
    patronList.forEach { println("Good evening, $it") }

    // 遍历方式三
    patronList.forEachIndexed { index, patron ->
        println("Good evening, $patron - you're #${index + 1} in line.")
    }

    // 从文件读取酒水数据
    val menuList = File("data/tavern-menu-items.txt").readText().split("\n")
    menuList.forEachIndexed { index, data -> println("$index : $data") }

    // 析构
    val (a, b, c) = patronList
    println("$a, $b, $c")

    // 通过使用_符号过滤不想要的元素
    val (goldMedal, _, bronzeMedal) = patronList
    println("$goldMedal, $bronzeMedal")

    // --- 学习 set ---
    val planets = setOf("Mercury", "Venus", "Earth")
    println(planets)

    // Set 集合不会对其元素做索引排序。这表明，它没有内置[]操作符供你按索引存取集合元素。 不过，使用内部靠遍历来做事的函数
    println(planets.elementAt(0))
    println(planets.elementAt(2))

    // 和 MutableList 一样，MutableSet 也支持增删元素
    val mutablePlanets = planets.toMutableSet()

    // 集合转换
    // 例如结合使用 toSet 和 toList 函数 可以实现去重。
    // 由于这种转来转去的用法太常见了，Kotlin 干脆封装了对 toSet 和 toList 函数的调用逻辑，提供了 distinct 这样一个快捷函数。
    val patrons = listOf("Eli Baggins", "Eli Baggins", "Eli Ironfoot").distinct()
    println(patrons)

    val playerAges: IntArray = intArrayOf(34, 27, 14, 52, 101)
    println(playerAges.javaClass)
    println(playerAges)
    // Array 编译为原始类型数组，其元素为引用类型。
    val ages = arrayOf(34, 27, 14, 52, 101)
    println(ages.javaClass)
    println(ages)
    // 数组的格式化输出
    println("Program arguments: ${ages.joinToString()}")


    // --- map ---
    // to 看上去像关键字，但事实上，它是个省略了点号和参数圆括号的特殊函数。 to 函数将它左边和右边的值转化成一个对（Pair）
    val patronGold = mutableMapOf("Eli" to 10.5, "Mordoc" to 8.0, "Sophie" to 5.5)
    println(patronGold)

    // 新加入的键值对就替换了重复的键值对
    println(mapOf("Eli" to 10.75, "Mordoc" to 8.25, "Sophie" to 5.50, "Sophie" to 6.25))

    // 读取 Map 集合的值
    println(patronGold)
    println(patronGold["Eli"])
    println(patronGold["notExist"])

    patronGold += "Eli" to 5.0
    patronGold["1"] = 2.0
    println(patronGold)
    // 修改值
    patronGold["1"] = 5.0

    // 遍历
    patronGold.forEach { (key, value) -> println("$key, balance: ${"%.2f".format(value)}") }
}
